package com.starblink.android.basic.util;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.widget.ImageView;

import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.PathUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.MultiTransformation;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.FitCenter;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.shuyu.gsyvideoplayer.utils.CommonUtil;
import com.starblink.android.basic.ext.progress.GlideProgressExtensionKt;
import com.starblink.android.basic.ext.progress.GlideProgressListener;
import com.starblink.basic.autosize.utils.AutoSizeUtils;
import com.starblink.basic.util.ActivityStackManage;
import com.starblink.basic.util.log.YYLogUtils;

import java.io.File;
import java.util.List;

import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner;
import jp.wasabeef.glide.transformations.CropCircleWithBorderTransformation;

/**
 * Glide工具类
 */
public class ImageUtils {
    /*** 占位图 */
    public static int placeholderImage = com.starblink.basic.style.R.mipmap.default_white;
    public static int placeholderImage2 = com.starblink.basic.style.R.drawable.one_page_skeleton_7;
    /*** 人像占位图 */
    public static int placeholderAvatarImage = com.starblink.basic.style.R.mipmap.mine_default_avatar;
    /*** 错误图 */
    public static int errorImage = com.starblink.basic.style.R.mipmap.error_img;
    public static int errorImage2 = com.starblink.basic.style.R.mipmap.default_img;
    public static float completeNum = 100f;

    /**
     * 加载图片(默认)
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     */
    public static void loadImage(Context context, String url, ImageView imageView) {
        RequestOptions options = new RequestOptions()
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);

    }

    public static void loadImage(Context context, String url, ImageView imageView, int placeholderImage, int errorImage) {
        if (context instanceof Activity && ((Activity) context).isDestroyed()) {
            return;
        }

        RequestOptions options = new RequestOptions()
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).diskCacheStrategy(DiskCacheStrategy.RESOURCE).apply(options).into(imageView);
    }


    /**
     * 加载图片(自定义处理方式)
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @note 如果ImageUtils中有能够满足需求的方法，优先使用它们
     */
    public static void loadImage(Context context, String url, ImageView imageView, int placeholderImage, int errorImage,
                                 Transformation<Bitmap> transformation) {
        RequestOptions options = RequestOptions.bitmapTransform(transformation)
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);
    }

    public static void loadImage(Context context, String url, ImageView imageView, RequestOptions options) {
        if (context instanceof Activity && ((Activity) context).isDestroyed()) {
            return;
        }

        RequestBuilder<Drawable> rb = Glide.with(context).load(url).diskCacheStrategy(DiskCacheStrategy.RESOURCE);
        if (options != null) {
            rb.apply(options);
        }
        rb.into(imageView);
    }

    /**
     * 对白底图的正片叠底功能的方法
     *
     * @param context
     * @param url
     * @param imageView
     * @param owner
     */
    public static void loadImageFilterTransSkGray100(String url, ImageView imageView, LifecycleOwner owner) {
        if (url == null || "".equals(url)) {
            return;
        }
        RequestOptions options = new RequestOptions()
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(ActivityStackManage.currentActivity())
                .load(url).apply(options).into(imageView);


        GlideProgressExtensionKt.loadWithProgress(
                // Glide RequestManager或RequestBuilder
                Glide.with(ActivityStackManage.currentActivity()),
                // 上下文
                ActivityStackManage.currentActivity(),
                // 图片网络地址
                url,
                new GlideProgressListener<Drawable>() {
                    @Override
                    public void onProgress(long current, long total, float percent) {
                    }

                    @Override
                    public void onFailed(@Nullable GlideException e, @Nullable Object model, @Nullable Target<Drawable> target, boolean isFirstResource) {
                        super.onFailed(e, model, target, isFirstResource);
//                        YYLogUtils.("loadImageFilterTransSkGray100，onFailed");
                    }

                    @Override
                    public void onSuccess(@Nullable Drawable resource, @Nullable Object model, @Nullable Target<Drawable> target, @Nullable DataSource dataSource, boolean isFirstResource) {
                        super.onSuccess(resource, model, target, dataSource, isFirstResource);
//                        YYLogUtils.e("loadImageFilterTransSkGray100，onSuccess");
                        try {
//                            YYLogUtils.e("loadImageFilterTransSkGray100，图片加底色");
                            imageView.setColorFilter(new PorterDuffColorFilter(Color.parseColor("#F7F7F7"), PorterDuff.Mode.MULTIPLY));
                        } catch (Exception e) {
                            YYLogUtils.e("loadImageFilterTransSkGray100，图片加底色失败");
                        }
                    }
                }, // 进度监听，可为空
                // 生命周期感知，生命周期结束时自动解除监听，可为空
                owner,
                // 进度条，可为空
                null,
                // 进度文本(x%)，可为空
                null
        ).apply(options).into(imageView);

        //kotlin写法 带原贴链接↓
        /**
         * Glide.with(this)
         *             .loadWithProgress(
         *                 context = this, // 上下文
         *                 networkUrl = "https://data.1freewallpapers.com/download/surreal-landscape-4k.jpg", // 图片网络地址
         *                 progressBar = binding.pbTest,  // 进度条，可为空
         *                 progressTextView = binding.tvTest, // 进度文本(x%)，可为空
         *                 lifecycleOwner = this,// 生命周期感知，生命周期结束时自动解除监听，可为空
         *                 listener = object : com.arcns.glide.grogress.GlideProgressListener<Drawable>() {  // 进度监听，可为空
         *                     override fun onProgress(current: Long, total: Long, percent: Float) {
         *                         Log.e("GlideProgress", "current:$current,total:$total,percent:$percent")
         *                     }
         *                 }
         *             )
         *             .skipMemoryCache(true)
         *             .diskCacheStrategy(DiskCacheStrategy.NONE)
         *             .into(binding.ivTest)
         * ————————————————
         * 版权声明：本文为CSDN博主「@Arcns」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
         * 原文链接：https://blog.csdn.net/fengzhongdiyin/article/details/128279522
         */

    }

    /**
     * 对白底图的正片叠底功能的方法
     *
     * @param context
     * @param url
     * @param imageView
     * @param owner
     */
    public static void loadImageFilterTransSkGray100(String url, ImageView imageView, LifecycleOwner owner, int bgColor) {
        if (url == null || "".equals(url)) {
            return;
        }
        RequestOptions options = new RequestOptions()
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(ActivityStackManage.currentActivity())
                .load(url).apply(options).into(imageView);


        GlideProgressExtensionKt.loadWithProgress(
                // Glide RequestManager或RequestBuilder
                Glide.with(ActivityStackManage.currentActivity()),
                // 上下文
                ActivityStackManage.currentActivity(),
                // 图片网络地址
                url,
                new GlideProgressListener<Drawable>() {
                    @Override
                    public void onProgress(long current, long total, float percent) {
                    }

                    @Override
                    public void onFailed(@Nullable GlideException e, @Nullable Object model, @Nullable Target<Drawable> target, boolean isFirstResource) {
                        super.onFailed(e, model, target, isFirstResource);
//                        YYLogUtils.("loadImageFilterTransSkGray100，onFailed");
                    }

                    @Override
                    public void onSuccess(@Nullable Drawable resource, @Nullable Object model, @Nullable Target<Drawable> target, @Nullable DataSource dataSource, boolean isFirstResource) {
                        super.onSuccess(resource, model, target, dataSource, isFirstResource);
//                        YYLogUtils.e("loadImageFilterTransSkGray100，onSuccess");
                        try {
//                            YYLogUtils.e("loadImageFilterTransSkGray100，图片加底色");
                            imageView.setColorFilter(new PorterDuffColorFilter(bgColor, PorterDuff.Mode.MULTIPLY));
                        } catch (Exception e) {
                            YYLogUtils.e("loadImageFilterTransSkGray100，图片加底色失败");
                        }
                    }
                }, // 进度监听，可为空
                // 生命周期感知，生命周期结束时自动解除监听，可为空
                owner,
                // 进度条，可为空
                null,
                // 进度文本(x%)，可为空
                null
        ).apply(options).into(imageView);
    }

    /**
     * 对白底图的正片叠底功能的方法
     *
     * @param context
     * @param url
     * @param imageView
     * @param owner
     */
    public static void loadImageFilterTrans(Context context, String url, ImageView imageView, LifecycleOwner owner, int bgColor, int width, int height) {
        RequestOptions options = new RequestOptions()
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context)
                .load(url).override(width, height).apply(options).into(imageView);


        GlideProgressExtensionKt.loadWithProgress(
                // Glide RequestManager或RequestBuilder
                Glide.with(context),
                // 上下文
                context,
                // 图片网络地址
                url,
                new GlideProgressListener<Drawable>() {
                    @Override
                    public void onProgress(long current, long total, float percent) {
                        if (percent == completeNum) {
                            try {
                                imageView.setColorFilter(new PorterDuffColorFilter(bgColor, PorterDuff.Mode.MULTIPLY));
                            } catch (Exception e) {
                                YYLogUtils.e("图片加载异常");
                            }
                        }
                    }
                }, // 进度监听，可为空
                // 生命周期感知，生命周期结束时自动解除监听，可为空
                owner,
                // 进度条，可为空
                null,
                // 进度文本(x%)，可为空
                null
        ).apply(options).into(imageView);

    }


    public static void loadImage(Context context, String url, int width, int height, ImageView imageView) {
        RequestOptions options = new RequestOptions()
                .placeholder(placeholderImage) //占位图
                .override(width, height)
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);

    }

    /**
     * 指定图片大小;使用override()方法指定了一个图片的尺寸。
     * Glide现在只会将图片加载成width*height像素的尺寸，而不会管你的ImageView的大小是多少了。
     * 如果你想加载一张图片的原始尺寸的话，可以使用Target.SIZE_ORIGINAL关键字----override(Target.SIZE_ORIGINAL)
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param width     图片宽度
     * @param height    图片高度
     */
    public static void loadImageSize(Context context, String url, ImageView imageView, int width, int height) {
        RequestOptions options = new RequestOptions()
                .placeholder(placeholderImage) //占位图
                .error(errorImage)             //错误图
                .override(width, height)
                .priority(Priority.HIGH);
        Glide.with(context).load(url).apply(options).into(imageView);
    }

    /**
     * 禁用内存缓存功能
     * diskCacheStrategy()方法基本上就是Glide硬盘缓存功能的一切，它可以接收五种参数：
     * <p>
     * DiskCacheStrategy.NONE： 表示不缓存任何内容。
     * DiskCacheStrategy.DATA： 表示只缓存原始图片。
     * DiskCacheStrategy.RESOURCE： 表示只缓存转换过后的图片。
     * DiskCacheStrategy.ALL ： 表示既缓存原始图片，也缓存转换过后的图片。
     * DiskCacheStrategy.AUTOMATIC： 表示让Glide根据图片资源智能地选择使用哪一种缓存策略（默认选项）。
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     */

    public static void loadImageSizeKipMemoryCache(Context context, String url, ImageView imageView) {
        RequestOptions options = new RequestOptions()
                .placeholder(placeholderImage) //占位图
                .error(errorImage)             //错误图
                .skipMemoryCache(true);          //禁用掉Glide的内存缓存功能
        Glide.with(context).load(url).apply(options).into(imageView);

    }

    /**
     * 预先加载图片
     * 在使用图片之前，预先把图片加载到缓存，调用了预加载之后，我们以后想再去加载这张图片就会非常快了，
     * 因为Glide会直接从缓存当中去读取图片并显示出来
     *
     * @param context 上下文
     * @param url     链接
     */
    public static void preloadImage(Context context, String url) {
        if (url != null && !url.isEmpty()) {
            Glide.with(context).load(url).preload();
        }
    }

    public static void preloadImage(Context context, List<String> urls) {
        if (urls == null) return;
        for (String url : urls) {
            preloadImage(context, url);
        }
    }

    /**
     * 加载圆形图片
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     */
    public static void loadCircleImage(Context context, String url, ImageView imageView) {
        RequestOptions options = new RequestOptions()
                .centerCrop()
                .circleCrop()//设置圆形
                .placeholder(placeholderImage) //占位图
                .error(errorImage)             //错误图
                .priority(Priority.HIGH);
        Glide.with(context).load(url).apply(options).into(imageView);
    }

    /**
     * 加载圆形带边框图片
     *
     * @param context     上下文
     * @param url         链接
     * @param imageView   ImageView
     * @param borderSize  边框宽度 px
     * @param borderColor 边框颜色
     */
    public static void loadCircleWithBorderImage(Context context, String url, ImageView imageView,
                                                 float borderSize, @ColorInt int borderColor) {
        RequestOptions options = RequestOptions.bitmapTransform(
                        new MultiTransformation<>(
                                new CenterCrop(),
                                new CropCircleWithBorderTransformation(CommonUtil.px2dip(context, borderSize), borderColor)
                        ))
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);
    }


    /**
     * 加载圆形带边框图片
     *
     * @param context     上下文
     * @param url         链接
     * @param imageView   ImageView
     * @param borderSize  边框宽度 px
     * @param borderColor 边框颜色
     */
    public static void loadCircleWithBorderFitCenterImage(Context context, String url, ImageView imageView,
                                                          float borderSize, @ColorInt int borderColor) {
        RequestOptions options = RequestOptions.bitmapTransform(
                        new MultiTransformation<>(
                                new FitCenter()
                        ))
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);
    }

    /**
     * 加载圆角图片
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param radius    圆角 px
     */
    public static void loadRoundCircleImage(Context context, String url, ImageView imageView,
                                            int radius) {
        RequestOptions options = RequestOptions.bitmapTransform(
                        new MultiTransformation<>(
                                new CenterCrop(),
                                new RoundedCornerTransformation(context, radius)
                        ))
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);
    }

    /**
     * @param context
     * @param url
     * @param imageView
     * @param width
     * @param height
     * @param radius    单位dp
     */
    public static void loadRoundCircleImage(Context context, String url, ImageView imageView, int width, int height,
                                            int radius) {
        RequestOptions options = RequestOptions.bitmapTransform(
                        new MultiTransformation<>(
                                new CenterCrop(),
                                new RoundedCornerTransformation(context, radius)
                        ))
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).override(width, height).apply(options).into(imageView);
    }


    /**
     * 加载圆角图片-指定任意部分圆角（图片上、下、左、右四个角度任意定义）
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param radius    圆角 px
     */
    public static void loadRoundCircleImage(Context context, String url, ImageView imageView,
                                            float radius, boolean leftTop, boolean rightTop, boolean leftBottom, boolean rightBottom) {
        RequestOptions options = RequestOptions.bitmapTransform(
                        new MultiTransformation<>(
                                new CenterCrop(),
                                new CornerTransform(context, AutoSizeUtils.dp2px(radius), leftTop, rightTop, leftBottom, rightBottom)
                        ))
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);
    }

    /**
     * 加载模糊图片（自定义透明度）
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param blur      模糊度，一般1-100够了，越大越模糊
     */
    public static void loadBlurImage(Context context, String url, ImageView imageView, int blur) {
        RequestOptions options = RequestOptions.bitmapTransform(
                        new MultiTransformation<>(
                                new CenterCrop()
//                                new BlurTransformation(blur)
                        ))
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);
    }

    /**
     * 加载模糊图片（自定义透明度）
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param blur      模糊度，一般1-100够了，越大越模糊
     * @param sampling  取样
     */
    public static void loadBlurImage(Context context, String url, ImageView imageView, int blur, int sampling) {
        RequestOptions options = RequestOptions.bitmapTransform(
                        new MultiTransformation<>(
                                new CenterCrop()
//                                new BlurTransformation(blur, sampling),
                        ))
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);
    }

    /**
     * 加载灰度(黑白)图片（自定义透明度）
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     */
    public static void loadBlackImage(Context context, String url, ImageView imageView) {
        RequestOptions options = RequestOptions.bitmapTransform(
                        new MultiTransformation<>(
                                new CenterCrop()
//                                new GrayscaleTransformation()
                        ))
                .placeholder(placeholderImage) //占位图
                .error(errorImage);            //错误图
        Glide.with(context).load(url).apply(options).into(imageView);
    }

    /**
     * Glide.with(this).asGif()    //强制指定加载动态图片
     * 如果加载的图片不是gif，则asGif()会报错， 当然，asGif()不写也是可以正常加载的。
     * 加入了一个asBitmap()方法，这个方法的意思就是说这里只允许加载静态图片，不需要Glide去帮我们自动进行图片格式的判断了。
     * 如果你传入的还是一张GIF图的话，Glide会展示这张GIF图的第一帧，而不会去播放它。
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     */
    public static void loadGif(Context context, String url, ImageView imageView) {
        RequestOptions options = new RequestOptions()
                .placeholder(placeholderImage2) //占位图
                .error(errorImage);            //错误图

        //只加载一次
//        Glide.with(this).load("url").diskCacheStrategy(DiskCacheStrategy.SOURCE).into(new GlideDrawableImageViewTarget(iv, 1));

//        Glide.with(this).load(url).asGif().diskCacheStrategy(DiskCacheStrategy.SOURCE).into(imageView)
        Glide.with(context).asGif()
                .load(url)
                .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
                .apply(options)
                .into(imageView);

//            .listener(new RequestListener<Drawable>() {
//            @Override
//            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
//                return false;
//            }
//
//            @Override
//            public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, com.bumptech.glide.load.DataSource dataSource, boolean isFirstResource) {
//                return false;
//            }
//
//        })
    }

    /**
     * 下载图片
     * 在RequestListener的onResourceReady方法里面获取下载File图片
     * new RequestListener<File>() {
     * *@Override
     * public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<File> target, boolean isFirstResource) {
     * return false;
     * }
     * <p>
     * *@Override
     * public boolean onResourceReady(File resource, Object model, Target<File> target, DataSource dataSource, boolean isFirstResource) {
     * //resource即为下载取得的图片File
     * return false;
     * }
     * }
     *
     * @param context         上下文
     * @param url             下载链接
     * @param requestListener 下载监听
     */
    public static void downloadImage(final Context context, final String url, RequestListener<File> requestListener) {
        Glide.with(context)
                .downloadOnly()
                .load(url)
                .addListener(requestListener).preload();
    }

    /**
     * 保存到相册中
     *
     * @param context 上下文
     * @param srcPath 网络图保存到本地的缓存文件路径
     */
    public static String saveToAlbum(Context context, String srcPath) {
        String dcimPath = PathUtils.getExternalDcimPath();
        File file = new File(dcimPath, "content_" + System.currentTimeMillis() + ".png");
        boolean isCopySuccess = FileUtils.copy(srcPath, file.getAbsolutePath());
        if (isCopySuccess) {
            //发送广播通知
            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file.getAbsolutePath())));
            return file.getAbsolutePath();
        } else {
            return "";
        }
    }

    //Android之不规则形状图片 使用遮罩就可以实现不规则形状的图片
    public static Bitmap maskBitmap(Bitmap original, Bitmap mask, int width, int height) {
        //根据透明度创建一个新的bitmap，需要注意的是这里的第三个参数的值Bitmap.Config.ARGB_8888表示支持32位图片，也就是支持透明通道。
        Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        //将遮罩层的图片放到画布中
        Canvas mCanvas = new Canvas(result);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //设置图层混合模式
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //一次绘制图层
        RectF rectN = new RectF(0f, 0f, width, height);
        mCanvas.drawBitmap(original, null, rectN, null);
        //计算mask的绘制比例
        Matrix mMatrix = new Matrix();
        //这里有个小坑，别忘了getWidth和getHeight的值转为float，不然算出来的也是整数。
        mMatrix.setScale((float) width / (float) mask.getWidth(), (float) height / (float) mask.getHeight());
        mCanvas.drawBitmap(mask, mMatrix, paint);
        paint.setXfermode(null);
        mCanvas.save();
        mCanvas.restore();
        return result;
    }


}

